#include "udp.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <arpa/inet.h>

//#include "DiffGnss.h"
//char SERVER_IP_ADDRESS[20]="192.168.1.103";


int PrintDiff(diff_t *diff)
{
    printf("\n\n-----------------------\n");
    printf("tow   : %f\n", diff->tow);
    printf("numBds: %d\n", diff->numBds);
    printf("numGps: %d\n", diff->numGps);
    printf("numGln: %d\n", diff->numGln);
    int j;
    printf("system: ");
    for (j = 0; j < MAXSAT; ++j)
    {
        printf("%d ", diff->system[j]);
    }
    printf("\n");

    printf("PRN: ");
    for (j = 0; j < MAXSAT; ++j)
    {
        printf("%d ", diff->PRN[j]);
    }
    printf("\n");

    printf("dDO: ");
    for (j = 0; j < MAXSAT; ++j)
    {
        printf("%f ", diff->dDO[j]);
    }
    printf("\n");

    printf("dPR: ");
    for (j = 0; j < MAXSAT; ++j)
    {
        printf("%f ", diff->dPR[j]);
    }
    printf("\n");

    printf("------------------------------------\n");
}

int server_len;
int client_len;


#define RECV_LOOP_COUNT 10
int recv_within_time(int fd, char *buf, size_t buf_n,struct sockaddr* addr,socklen_t *len,unsigned int sec,unsigned usec)
{
    struct timeval tv;
    fd_set readfds;
    int i=0;
    unsigned int n=0;
    for(i=0;i<RECV_LOOP_COUNT;i++)
    {
        FD_ZERO(&readfds);
        FD_SET(fd,&readfds);
        tv.tv_sec=sec;
        tv.tv_usec=usec;
        select(fd+1,&readfds,NULL,NULL,&tv);
        if(FD_ISSET(fd,&readfds))
        {
            if((n=recvfrom(fd,buf,buf_n,0,addr,len))>=0)
            {    
                return n;
            }
        }
    }
    return -1;
}

int rover_sock_fd;/*套接字文件描述符*/
struct sockaddr_in addr_rover_server;
int UdpRoverInit(char *server_ip)
{
	char SERVER_IP_ADDRESS[20]="127.0.0.1";
    strcpy(SERVER_IP_ADDRESS, server_ip);


    rover_sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子
    //初始化服务器端地址
    memset(&addr_rover_server,0,sizeof(addr_rover_server));
    addr_rover_server.sin_family = AF_INET;
    addr_rover_server.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);
    addr_rover_server.sin_port = htons(SERVER_PORT);

    server_len = sizeof(struct sockaddr_in);
    //printf("begin:\n");
    return rover_sock_fd;
}

/*
int UdpRoverRequest(unsigned char *request_data)
{
    int i;
    int send_num;
    unsigned char send_buf[MAX_LEN_ONCE];
    for(i=0;i<strlen(request_data)/MAX_LEN_ONCE+1;++i)
    {
        strncpy(send_buf,send_buf+i*MAX_LEN_ONCE,MAX_LEN_ONCE);

        send_num = sendto(sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server,server_len);
        if(send_num < 0){
                perror("sendto");
                return -1;
        } else{
        
                //printf("send sucessful:%s\n",send_buf);
        }
        usleep(10);
    }

    return 0;
}
*/

int UdpRoverRecieve(diff_t *diff)
{
	int recv_num, i=0;
	unsigned char recv_buf[MAX_LEN_ONCE];
    unsigned char send_buf[MAX_LEN_ONCE];

    unsigned char *_dest=malloc(sizeof(diff_t)+MAX_LEN_ONCE);
    memset((void *)_dest,0,sizeof(diff_t)+MAX_LEN_ONCE);

    //发送命令
    memset(send_buf,0,MAX_LEN_ONCE);
    strcpy(send_buf,"\nrover_get\n");
    //do
        sendto(rover_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_rover_server,server_len);
        usleep(5);
        while(1)
        {
            recv_num = recv_within_time(rover_sock_fd,recv_buf,MAX_LEN_ONCE,(struct sockaddr *)&addr_rover_server,&server_len,0,1000);
            if (recv_num<MAX_LEN_ONCE)
            {
                continue;
            }
            if(strncmp(recv_buf,"\nserver_start\n",strlen("\nserver_start\n")))
            {
                putchar(recv_buf);
                printf("@@%d\n", recv_num);
                //return 1;
            }
            else{
                printf("good\n");
                break;}
        }   


    while(1) {
        recv_within_time(rover_sock_fd,recv_buf,MAX_LEN_ONCE,(struct sockaddr *)&addr_rover_server,&server_len,0,1000);
        if (!strncmp(recv_buf,"\nserver_end\n",strlen("\nserver_end\n"))) break;
        if (!strncmp("\nserver |",recv_buf,strlen("\nserver |")))
        {
            memcpy(_dest+i*(MAX_LEN_ONCE/2),recv_buf+(MAX_LEN_ONCE/2),MAX_LEN_ONCE/2);
            ++i;
        }
        printf(".");
    }

    printf("-------------%d------------\n", i);
    if (i!=sizeof(diff_t)/(MAX_LEN_ONCE/2)+1)
    {
        printf("%d ,get wrong, will not update this time!\n", i);
    }
    else{
        memcpy((void *)diff, _dest, sizeof(diff_t)+MAX_LEN_ONCE);
        if (1)
        {
            PrintDiff(diff);
        }
    }

    free(_dest);
    UdpClose(rover_sock_fd);
	return 0;
}

int station_sock_fd;
struct sockaddr_in addr_station_server;
int UdpStationInit(char *server_ip)
{
	char SERVER_IP_ADDRESS[20]="127.0.0.1";
    strcpy(SERVER_IP_ADDRESS, server_ip);


    station_sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子
    //初始化服务器端地址
    memset(&addr_station_server,0,sizeof(addr_station_server));
    addr_station_server.sin_family = AF_INET;
    addr_station_server.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);
    addr_station_server.sin_port = htons(SERVER_PORT);

    server_len = sizeof(struct sockaddr_in);
    printf("begin send:\n");

    return 0;
}
int UdpStationSend(diff_t *diff)
{
    int i=0;
    int send_num;

    unsigned char send_buf[MAX_LEN_ONCE];
    unsigned char *src = (unsigned char *)diff;

    memset(send_buf,0,MAX_LEN_ONCE);
    strcpy(send_buf,"\nstation_start\n");
    sendto(station_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_station_server,server_len);
    /*
    if(send_num < 0){
            perror("sendto");
            return -1;
    }
    */
        int j;
        for (j = 0; j < MAX_LEN_ONCE; ++j)
        {
            putchar(send_buf[j]);
        }

    for(i=0;i<sizeof(diff_t)/16+1;++i)
    {
        memset(send_buf,0,MAX_LEN_ONCE);
        strcpy(send_buf,"\nstation|");
        memcpy(send_buf+16,src+i*(MAX_LEN_ONCE/2),MAX_LEN_ONCE/2);


        for (j = 0; j < MAX_LEN_ONCE; ++j)
        {
            putchar(send_buf[j]);
        }

        send_num = sendto(station_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_station_server,server_len);
        /*
        if(send_num < 0){
                perror("sendto");
                return -1;
        }
        */
        usleep(10);
    }
    printf("---%d----%d----%d----%d----\n", i,sizeof(diff_t),MAX_LEN_ONCE/2,sizeof(diff_t)/(MAX_LEN_ONCE/2));

    memset(send_buf,0,MAX_LEN_ONCE);
    strcpy(send_buf,"\nstation_end\n");
    sendto(station_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_station_server,server_len);


        for (j = 0; j < MAX_LEN_ONCE; ++j)
        {
            putchar(send_buf[j]);
        }

    return 0;
}

/*
int server_tcp_fd, conn;
int TcpServerInit()
{
    int i;
    struct sockaddr_in addr;
    size_t addr_len = sizeof(addr);
    if(    (server_tcp_fd = socket(PF_INET,SOCK_STREAM,0)) < 0   )  // create socket TCP
    {
        perror("socket");
    }
    
    i = 1;
    setsockopt(server_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); //socket addr reuse
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;               //addr type ,must be AF_INET(IPv4)
    addr.sin_addr.s_addr = htonl(INADDR_ANY); //all IPs
    addr.sin_port = htons(TCP_PORT);
    if( bind(server_tcp_fd, (struct sockaddr *)&addr, sizeof(addr)) )
    {
        perror("bind");                     //bind socket to any addr,port = 8888
    }
    if (listen(server_tcp_fd,5))
    {
        perror("listen");  
    }
}


int TcpSend(diff_t *diff)
{
    while((conn = accept(server_tcp_fd, (struct sockaddr *)&addr, &addr_len) )<0 )
        break;
    {
        //printf("Accept! \nThis is TCPserver!\n%s:%d\n", inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));

        copy_data(conn);
        
        printf("Done");
        close(conn);
    }
    return 0;
}
*/
int server_sock_fd;   //套接子描述符号
struct sockaddr_in  addr_server, addr_server_client;
int UdpServerInit()
{
    int recv_num;
    int send_num;

    char recv_buf[MAX_LEN_ONCE];


    server_sock_fd = socket(AF_INET,SOCK_DGRAM,0);

    if(server_sock_fd < 0){
            perror("client socket");
            exit(1);
    } else{
            printf("client sock sucessful\n");
    }

    memset(&addr_server,0,sizeof(struct sockaddr_in));
    addr_server.sin_family = AF_INET;//协议族
    addr_server.sin_port = htons(SERVER_PORT);
    addr_server.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址

    client_len = sizeof(struct sockaddr_in);

    /*绑定套接字*/
    if(bind(server_sock_fd,(struct sockaddr *)&addr_server,sizeof(struct sockaddr_in))<0 ){
            perror("server bind");
            return -1;
    } else{
            printf("server bind sucess\n");
    }

    return 0;
}

int UdpServerLoop(diff_t *diff, int arg)
{
	int recv_num,send_num, i=0;
	unsigned char recv_buf[MAX_LEN_ONCE];
	unsigned char send_buf[MAX_LEN_ONCE];

    unsigned char *dest=malloc(sizeof(diff_t)+MAX_LEN_ONCE);
    memset((void *)dest,0,sizeof(diff_t)+MAX_LEN_ONCE);

    unsigned char *src = (unsigned char *)diff;
	while(1)
	{
		//update diff data
		recv_num = recvfrom(server_sock_fd,recv_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server_client,&client_len);
        int j;
        /*
        for (j = 0; j < MAX_LEN_ONCE; ++j)
        {
            putchar(recv_buf[j]);
        }
       */
        if(recv_num <0 ) {
            perror("recv_from");
            return -1;
	    } 

            //update diff data
	    	if (!strncmp(recv_buf,"\nstation_start\n",strlen("\nstation_start\n")))
	    	{
	    		i=0;
	    		while(1) {
	    			recv_num = recvfrom(server_sock_fd,recv_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server_client,&client_len);
	    			if(recv_num <0 ) {
                        perror("recv_from");
                        return -1;
                    } 

                    if (!strncmp(recv_buf,"\nstation_end\n",strlen("\nstation_end\n"))) break;
                    if (!strncmp("\nstation|",recv_buf,strlen("\nstation|")))
                    {
                        memcpy(dest+i*(MAX_LEN_ONCE/2),recv_buf+(MAX_LEN_ONCE/2),MAX_LEN_ONCE/2);
                        ++i;
                    }
	    			//printf("recv sucessful\n");

	    		}

                printf("-------------%d------------\n", i);
                if (i!=sizeof(diff_t)/(MAX_LEN_ONCE/2)+1)
                {
                    printf("get wrong, will not update this time!\n");
                }
                else{
                    memcpy((void *)diff, dest, sizeof(diff_t)+MAX_LEN_ONCE);
                    if (arg)
                    {
                        PrintDiff(diff);
                    }
                }

	    	}

            //send diff data
            if(!strncmp(recv_buf,"\nrover_get\n",strlen("\nrover_get\n")))
            {
                memset(send_buf,0,MAX_LEN_ONCE);
                strcpy(send_buf,"\nserver_start\n");
                sendto(server_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server_client,client_len);
                
                //以后要防溢出s
                for(i=0;i<sizeof(diff_t)/(MAX_LEN_ONCE/2)+1;++i)
                {
                    strcpy(send_buf,"\nserver |");
                    memcpy(send_buf+(MAX_LEN_ONCE/2),src+i*(MAX_LEN_ONCE/2),MAX_LEN_ONCE/2);
                    send_num = sendto(server_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server_client,client_len);
                    if(send_num < 0){
                            perror("sendto");
                            return -1;
                    } 
                    //usleep(20);

                }
                memset(send_buf,0,MAX_LEN_ONCE);
                strcpy(send_buf,"\nserver_end\n");
                sendto(server_sock_fd,send_buf,MAX_LEN_ONCE,0,(struct sockaddr *)&addr_server_client,client_len);
            }		
	}
    return 0;
}

int UdpClose(int sock_fd)
{
	close(sock_fd);
	return 0;
}